package util;

import com.alibaba.druid.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 字符串的下划线和驼峰格式互转工具
 */
public class RequestParamConvertor {

    public static final char UNDERLINE = '_';

    /**
     * 驼峰格式字符串转换为下划线格式字符串
     *
     * @param param
     * @return
     */
    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }


    /**
     * 下划线格式字符串转换为驼峰格式字符串2
     *
     * @param param
     * @return
     */
    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        StringBuilder sb = new StringBuilder(param);
        Matcher mc = Pattern.compile("_").matcher(param);
        int i = 0;
        while (mc.find()) {
            int position = mc.end() - (i++);
            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 下划线类型属性值复制到驼峰
     * @param underLineParam
     * @param camelParam
     */
    public static void underlineToCamelCopyProperty(Object underLineParam,Object camelParam) {
        List<Field> u_fields = getFieldList(underLineParam);
        try {
            for(Field u:u_fields){
                PropertyDescriptor u_pd = new PropertyDescriptor(u.getName(), underLineParam.getClass());
                //获得get方法
                Method get = u_pd.getReadMethod();
                Object u_Value = get.invoke(underLineParam);
                List<Field> c_fields = getFieldList(camelParam);
                for(Field c:c_fields){
                    if(StringUtils.equals(underlineToCamel(u.getName()),c.getName())){
                        PropertyDescriptor pd = new PropertyDescriptor(c.getName(), camelParam.getClass());
                        Method method = pd.getWriteMethod();
                        method.invoke(camelParam, new Object[]{u_Value});
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 驼峰类型属性值复制到下划线
     * @param underLineParam
     * @param camelParam
     */
    public static void camelToUnderlineCopyProperty(Object camelParam,Object underLineParam) {
        List<Field> c_fields = getFieldList(camelParam);
        try {
            for(Field c:c_fields){
                PropertyDescriptor c_pd = new PropertyDescriptor(c.getName(), camelParam.getClass());
                //获得get方法
                Method get = c_pd.getReadMethod();
                Object c_Value = get.invoke(camelParam);
                List<Field> u_fields = getFieldList(underLineParam);
                for(Field u:u_fields){
                    if(StringUtils.equals(camelToUnderline(c.getName()),u.getName())){
                        PropertyDescriptor pd = new PropertyDescriptor(u.getName(), underLineParam.getClass());
                        Method method = pd.getWriteMethod();
                        method.invoke(underLineParam, new Object[]{c_Value});
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static void copySetGetProperty(Object setBean,Object getBean,String setBeanName,String getBeanName) {
        StringBuilder builder = new StringBuilder();
        List<Field> c_fields = getFieldList(setBean);
        try {
            for(Field c:c_fields){
                PropertyDescriptor c_pd = new PropertyDescriptor(c.getName(), setBean.getClass());
                List<Field> u_fields = getFieldList(getBean);
                for(Field u:u_fields){
                    if(StringUtils.equals(underlineToCamel(c.getName()),u.getName())){
                        PropertyDescriptor pd = new PropertyDescriptor(u.getName(), getBean.getClass());
                        String setM = setBeanName+"."+c_pd.getWriteMethod().getName()+"("+getBeanName+"."+pd.getReadMethod().getName()+"());\r\n";
                        builder.append(setM);
                    }
                }
                //获得get方法
//                Method get = c_pd.getReadMethod();
//                Object c_Value = get.invoke(setBean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder.toString());
    }

    public static List<Field> getFieldList(Object o){
        List<Field> fieldList = Arrays.stream(o.getClass().getDeclaredFields()).filter(f -> {
            String name = f.getName();
            //过滤掉不需要修改的属性
            return !"id".equals(name) && !"serialVersionUID".equals(name);
        }).collect(Collectors.toList());
        return fieldList;
    }

    /**
     * 自动生成app服务接口请求参数类复制到下游对应请求参数的set/get方法
     * 使用方法：将app和下游服务接口的参数类复制到本目录下，
     * 修改方法里的对应类执行主方法即可打印出set方法
     * @param setBean
     * @param appReqBean
     * @param setBeanName
     * @param appReqBeanName
     */
    public static void copyAppProperty(Object setBean,Object appReqBean,String setBeanName,String appReqBeanName) {
        StringBuilder builder = new StringBuilder();
        List<Field> c_fields = getFieldList(setBean);
        try {
            for(Field c:c_fields){
                PropertyDescriptor c_pd = new PropertyDescriptor(c.getName(), setBean.getClass());
                List<Field> app_fields = getFieldList(appReqBean);
                for(Field app:app_fields){
                    if(StringUtils.equals(underlineToCamel(c.getName()),app.getName())){
                        PropertyDescriptor pd = new PropertyDescriptor(app.getName(), appReqBean.getClass());
                        String setM = setBeanName+"."+c_pd.getWriteMethod().getName()+"("+appReqBeanName+"."+pd.getReadMethod().getName()+"());\r\n";
                        builder.append(setM);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(builder.toString());
    }



    public static void main(String[] args) {
//        String aaa = "app_version_fld";
//        System.out.println(underlineToCamel(aaa));
//        aaa = "appVersionFld";
//        System.out.println(camelToUnderline(aaa));

        // 1-复制app服务请求参数属性到下游接口方法
        AppDemoReqForm appReqForm = new AppDemoReqForm();
        copySetGetProperty(appReqForm,appReqForm,"entity","dto");
    }


}
